# -*- coding: utf-8 -*-
"""
Created on Sat Aug 17 10:01:13 2024

@author: jzz
"""

# -*- coding: utf-8 -*-
"""
Created on Fri Jul 26 09:27:50 2024
输出不同回测时间段方向形式选择情况及最优参数

@author: jzz
"""

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as stats
import os
import copy
from dateutil.relativedelta import relativedelta
import datetime
import statsmodels.api as sm
import warnings
from scipy.stats import ttest_ind
from scipy.stats import f_oneway
import sys

def best_parm(form, result, grouped): 
    best_group = grouped.get_group((result, form))
    ten_max_row = best_group.nlargest(10, '绝对收益年化')
    # 替换 '是否带滤波' 列中的值并将其转换为整数
    ten_max_row['是否带滤波'] = ten_max_row['是否带滤波'].replace({'是': 1, '否': 0}).astype(int)
    fun_min = 1000
    row_best = None
    for i in range(0, 10,1):
        row = ten_max_row.iloc[i]
        fun = 0
        for j in range(0, 10):
            a = row['是否带滤波'] - ten_max_row['是否带滤波'].iloc[j]
            b = row['窗口'] - ten_max_row['窗口'].iloc[j]
            c = row['参数1'] - ten_max_row['参数1'].iloc[j]
            d = row['参数2'] - ten_max_row['参数2'].iloc[j]
            if result == '正':  # 取正的时候x1可取0.25、0.5、0.75，参数2可取0.5、0.75
                fun += a**2 + (b/(5-1))**2 + 1/2*(c/(0.75-0.25))**2 + 1/2*(d/(0.75-0.5))**2
            else:
                fun += a**2 + (b/(5-1))**2 + 1/2*(c/(0.5-0.25))**2 + 1/2*(d/(0.75-0.25))**2
        if fun < fun_min:
            fun_min = fun
            row_best = row.copy()
    # 将 row_best 的 '是否带滤波' 列转换回 '是' 或 '否'
    if row_best is not None:
        row_best['是否带滤波'] = '是' if row_best['是否带滤波'] == 1 else '否'
    return row_best
'''
def best_parm(form, result, grouped,i): 
    best_group = grouped.get_group((result, form))
    fifth_max_row = best_group.nlargest(i, '绝对收益年化').iloc[-1]
    return fifth_max_row
'''
def calculate_search_best(df, direction, direction_diff, para, i, flag1='方向', flag2='形式'):
    columns1 = ['代码','指标','形式', '逻辑方向','T检验p值','数据结果','最后结论', 
                '正向平均绝对年化收益','负向平均绝对年化收益',
                '是否滤波', '最优窗口', '最优参数1', '最优参数2',
                '最优参数下绝对年化收益']
    data_new = pd.DataFrame(columns=columns1)
    code=df['指标代码'].iloc[0]
    name=df['指标名称'].iloc[0]
    grouped = df.groupby(['方向', '形式'])
    positive_returns = grouped.get_group(('正', '原指标'))['绝对收益年化']
    positive_returns_diff = grouped.get_group(('正', '一阶差分'))['绝对收益年化']
    negative_returns = grouped.get_group(('负', '原指标'))['绝对收益年化']
    negative_returns_diff = grouped.get_group(('负', '一阶差分'))['绝对收益年化']
    t_stat, p_value = ttest_ind(positive_returns, negative_returns)
    t_stat_diff, p_value_diff = ttest_ind(positive_returns_diff, negative_returns_diff)
    if direction=='正':
        if positive_returns.mean() >= negative_returns.mean() and p_value<p_set:
            a = '正向显著好于负向'
            result = '正'
        elif p_value>=p_set:
            a = '不显著'
            result = '正'
        elif positive_returns.mean() <= negative_returns.mean() and p_value<p_set:
            a = '负向显著好于正向'
            result = '舍去'
    elif direction=='负':
        if positive_returns.mean() <= negative_returns.mean() and p_value<p_set:
            a = '负向显著好于正向'
            result = '负'
        elif p_value>=p_set:
            a = '不显著'
            result = '负'
        elif positive_returns.mean() >= negative_returns.mean() and p_value<p_set:
            a = '正向显著好于负向'
            result = '舍去'
    else:
        if positive_returns.mean() >= negative_returns.mean() and p_value<p_set:
            a = '正向显著好于负向'
            result = '正'
        elif positive_returns.mean() <= negative_returns.mean() and p_value<p_set:
            a = '负向显著好于负向'
            result = '负'
        elif p_value>=p_set:
            a = '不显著'
            result = '舍去'
    #columns1 = ['代码','指标','形式', '逻辑方向','T检验p值','数据结果','最后结论', 
                #'是否滤波', '最优窗口', '最优参数1', '最优参数2',
                #'最优参数下绝对年化收益']
    if result == '正' or result == '负':
        best_row = best_parm('原指标', result, grouped)
        new_row1 = [code,name,'原指标', direction, p_value, a, result, positive_returns.mean(),negative_returns.mean(),
                best_row['是否带滤波'], best_row['窗口'], best_row['参数1'], best_row['参数2'],
                best_row['绝对收益年化']]
        data_new.loc[len(data_new)] = new_row1
    else:
        new_row1 = [code,name,'原指标', direction, p_value, a, result, positive_returns.mean(),negative_returns.mean(),
                    '','','','','']
        data_new.loc[len(data_new)] = new_row1
            
    if direction_diff=='正':
        if positive_returns_diff.mean() >= negative_returns_diff.mean() and p_value_diff<p_set:
            a_diff = '正向显著好于负向'
            result_diff = '正'
        elif p_value_diff>=p_set:
            a_diff = '不显著'
            result_diff = '正'
        elif positive_returns_diff.mean() <= negative_returns_diff.mean() and p_value_diff<p_set:
            a_diff = '负向显著好于正向'
            result_diff = '舍去'
    elif direction_diff=='负':
        if positive_returns_diff.mean() <= negative_returns_diff.mean() and p_value_diff<p_set:
            a_diff = '负向显著好于正向'
            result_diff = '负'
        elif p_value_diff>=p_set:
            a_diff = '不显著'
            result_diff = '负'
        elif positive_returns_diff.mean() >= negative_returns_diff.mean() and p_value_diff<p_set:
            a_diff = '正向显著好于负向'
            result_diff = '舍去'
    else:
        if positive_returns_diff.mean() >= negative_returns_diff.mean() and p_value_diff<p_set:
            a_diff = '正向显著好于负向'
            result_diff = '正'
        elif positive_returns_diff.mean() <= negative_returns_diff.mean() and p_value_diff<p_set:
            a_diff = '负向显著好于负向'
            result_diff = '负'
        elif p_value_diff>=p_set:
            a_diff = '不显著'
            result_diff = '舍去'
    if result_diff == '正' or result_diff == '负':
        best_row_diff = best_parm('一阶差分', result_diff, grouped)
        new_row1_diff = [code,name,'一阶差分', direction_diff, p_value_diff, a_diff, result_diff, positive_returns_diff.mean(),negative_returns_diff.mean(),
                best_row_diff['是否带滤波'], best_row_diff['窗口'], best_row_diff['参数1'], best_row_diff['参数2'],
                best_row_diff['绝对收益年化']]
        data_new.loc[len(data_new)] = new_row1_diff
    else:
        new_row1_diff = [code,name,'一阶差分', direction_diff, p_value_diff, a_diff, result_diff,positive_returns_diff.mean(),negative_returns_diff.mean(),
                         '','','','','']
        data_new.loc[len(data_new)] = new_row1_diff
    return data_new


def main(industry='石油石化'):

    if start_date=='2015-12-31' and end_date==end_date:
        kk='全样本'
    elif start_date=='2021-12-31' and end_date==end_date:
        kk='2021年后'
    #elif start_date=='2015-12-31' and end_date=='2021-12-31':
        #kk='2021年前'
    
    
    root_dir=folder+industry+'/'+industry+kk
    df_flag=pd.read_excel(folder+industry+'/'+industry+'指标信息.xlsx')
    
    
    all_results = pd.DataFrame() 
    for subdir, dirs, _ in os.walk(root_dir):
        for dir_name in dirs:
            # 构建'参数及结果'文件的完整路径
            file_path = os.path.join(subdir, dir_name, '参数及结果.xlsx')
            df = pd.read_excel(file_path)
            code=df['指标代码'].iloc[0]
            indice = df_flag.index[df_flag['代码']==code].tolist()[0]
            direction=df_flag['原指标方向'].iloc[indice]
            direction_diff=df_flag['边际方向'].iloc[indice]
            df=df.sort_values(by=['方向', '形式', '是否带滤波','窗口' ,'参数1', '参数2'])
            results = calculate_search_best(df, direction, direction_diff, '方向选择及最优参数', '方向','形式')
            all_results = pd.concat([all_results, results], ignore_index=True)

    all_results.to_excel(folder+industry+'/'+industry+kk+'/'+industry+kk+'方向选择及最优参数''.xlsx', index=False)

#%% 主程序
industry_values = ['通信','房地产','公用事业',
              '家用电器','建筑材料','国防军工','传媒','纺织服饰',
              '机械设备','有色金属','基础化工','钢铁',
              '电力设备','电子','农林牧渔','建筑装饰',
              '煤炭','轻工制造','医药生物',
              '计算机','交通运输','美容护理','汽车',
              '商贸零售','食品饮料','社会服务','石油石化']
p_set=0.2
folder='C:/Users/jzz/Desktop/全行业-无未来数据 -选10个里面距离最小的/'
#修改回测时间段
start_date='2015-12-31'
end_date='2021-12-31'
# 循环运行 my_script.py，并传递不同的 a 值

for industry in industry_values:
    main(industry)
    print(industry)    
